package com.by.log;

import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 全链路追踪上下文
 * 用于在分布式系统中传递追踪信息
 */
public class TraceContext {
    private static final ThreadLocal<TraceContext> CONTEXT_HOLDER = new ThreadLocal<TraceContext>() {
        @Override
        protected TraceContext initialValue() {
            return new TraceContext();
        }
    };

    /**
     * 追踪ID，用于标识一次完整的请求链路
     */
    private String traceId;

    /**
     * 当前跨度ID，用于标识当前操作
     */
    private String spanId;

    /**
     * 父跨度ID，用于标识当前操作的父操作
     */
    private String parentSpanId;

    /**
     * 附加属性，用于存储额外的追踪信息
     */
    private final Map<String, String> attributes = new ConcurrentHashMap<>();

    private TraceContext() {
    }

    public static TraceContext getCurrentContext() {
        return CONTEXT_HOLDER.get();
    }

    public static void setCurrentContext(TraceContext context) {
        CONTEXT_HOLDER.set(context);
    }

    public static void clear() {
        CONTEXT_HOLDER.remove();
    }

    public String getTraceId() {
        return traceId;
    }

    public void setTraceId(String traceId) {
        this.traceId = traceId;
    }

    public String getSpanId() {
        return spanId;
    }

    public void setSpanId(String spanId) {
        this.spanId = spanId;
    }

    public String getParentSpanId() {
        return parentSpanId;
    }

    public void setParentSpanId(String parentSpanId) {
        this.parentSpanId = parentSpanId;
    }

    public Map<String, String> getAttributes() {
        return attributes;
    }

    public String getAttribute(String key) {
        return attributes.get(key);
    }

    public void setAttribute(String key, String value) {
        attributes.put(key, value);
    }

    public void removeAttribute(String key) {
        attributes.remove(key);
    }

    /**
     * 生成新的追踪ID
     * @return 新的追踪ID
     */
    public static String generateTraceId() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 生成新的跨度ID
     * @return 新的跨度ID
     */
    public static String generateSpanId() {
        return String.valueOf(System.nanoTime());
    }
}